/**
    Copyright (c) 2009 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "GUI.h"
#include "BitonicSortMgr.h"

extern GUI                            g_gui;
extern BitonicSortMgr                g_bitonicSortMgr;

#define IDC_SORT_MODE_CB                10000
#define IDC_SORT_DIR_CB                    10001
#define IDC_RESET_DATA_CHECKBOX            10002
#define IDC_BEGIN_SORT_BTN                10003

void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );


GUI::GUI() : m_pTxtHelper( NULL ), m_pSortModeCB( NULL ), m_pSortDirCB( NULL ), m_pSortButton( NULL )
{
}

/**
    @param pd3dDevice    [in]    D3D Device
*/
HRESULT GUI::Create( ID3D11Device* pd3dDevice )
{
    HRESULT hr = S_OK;

    ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();
    V_RETURN( m_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) );
    m_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &m_DialogResourceManager, 15 );

     return hr;
}

/**
*/
void GUI::RegistGuiItems()
{
    m_SampleUI.Init( &m_DialogResourceManager );

    // sort mode combobox
    m_SampleUI.AddComboBox( IDC_SORT_MODE_CB, 0, 150, 150, 24, 'M', false, &m_pSortModeCB );
    m_pSortModeCB->AddItem( L"Recursive Sort", IntToPtr(SORT_MODE_RECURSIVE) );
    m_pSortModeCB->AddItem( L"Loop Sort", IntToPtr(SORT_MODE_LOOP_ONE_STEP) );
    m_pSortModeCB->AddItem( L"Loop Sort Demo", IntToPtr(SORT_MODE_LOOP_MULT_STEP) );    
    m_pSortModeCB->SetSelectedByIndex( g_bitonicSortMgr.GetSortMode() );
    m_pSortModeCB->SetTextColor( D3DCOLOR_XRGB( 0, 0, 255 ) );

    // sort dir combobox
    m_SampleUI.AddComboBox( IDC_SORT_DIR_CB, 0, 180, 150, 24, 'D', false, &m_pSortDirCB );
    m_pSortDirCB->AddItem( L"Sort Dir UP", IntToPtr(SORT_DIR_UP) );
    m_pSortDirCB->AddItem( L"Sort Dir DOWN", IntToPtr(SORT_DIR_DOWN) );    
    m_pSortDirCB->SetSelectedByIndex( g_bitonicSortMgr.GetSortDir() );
    m_pSortDirCB->SetTextColor( D3DCOLOR_XRGB( 0, 0, 255 ) );

    // reset data checkbox
    m_SampleUI.AddCheckBox( IDC_RESET_DATA_CHECKBOX, L"Reset Data", 0, 210, 150, 24, g_bitonicSortMgr.GetResetData(), 'R', true, &m_pResetDataCheckBox );
    m_pResetDataCheckBox->SetTextColor( D3DCOLOR_XRGB( 0, 0, 255 ) );

    // begin sort button
    m_SampleUI.AddButton( IDC_BEGIN_SORT_BTN, L"Begin Sorting", 0, 240, 150, 24, 'S', true, &m_pSortButton );
    m_pSortButton->SetTextColor( D3DCOLOR_XRGB( 0, 0, 255 ) );

    m_SampleUI.SetCallback( OnGUIEvent ); 
}

/**
    @param fElapsedTime        [in]        elapsed time
*/
void GUI::FrameRender( float fElapsedTime )
{
    m_SampleUI.OnRender( fElapsedTime );
    RenderText();
}

/**
*/
void GUI::RenderText()
{
    m_pTxtHelper->Begin();
    m_pTxtHelper->SetInsertionPos( 2, 0 );
    m_pTxtHelper->SetForegroundColor( D3DXCOLOR( 0.0f, 0.0f, 1.0f, 1.0f ) );
    m_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    m_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
    m_pTxtHelper->End();
}

/**
    @param pd3dDevice        [in]    D3D Device
    @param pBackBufferDesc    [in]    Description of backbuffer
*/
HRESULT GUI::ResizedSwapChain( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc )
{
    HRESULT hr = S_OK;
    V_RETURN( m_DialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );

    m_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 280 );
    m_SampleUI.SetSize( 150, 110 );

    return hr;
}

/**
*/
void GUI::Destroy()
{
    m_DialogResourceManager.OnD3D11DestroyDevice();
    SAFE_DELETE( m_pTxtHelper );    
}

/**
*/
LRESULT GUI::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
{
    // Pass messages to dialog resource manager calls so GUI state is updated correctly
    *pbNoFurtherProcessing = m_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;

    *pbNoFurtherProcessing = m_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;    

    return 0;
}

/**
    CDXUTDialog callback.
*/
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{
    switch( nControlID )
    {
        case IDC_SORT_MODE_CB:
        {
            CDXUTComboBox* pComboBox = ( CDXUTComboBox* )pControl;
            g_bitonicSortMgr.SetSortMode( static_cast< SortMode >( PtrToInt( pComboBox->GetSelectedData() ) ) );
            break;
        }        
        case IDC_SORT_DIR_CB:
        {
            CDXUTComboBox* pComboBox = ( CDXUTComboBox* )pControl;
            g_bitonicSortMgr.SetSortDir( static_cast< SortDir >( PtrToInt( pComboBox->GetSelectedData() ) ) );
            break;
        }
        case IDC_RESET_DATA_CHECKBOX:
        {
            CDXUTCheckBox* pCheckBox = ( CDXUTCheckBox* )pControl;
            g_bitonicSortMgr.SetResetData( pCheckBox->GetChecked() );
            break;
        }
        case IDC_BEGIN_SORT_BTN:
        {
            g_bitonicSortMgr.BeginSort();
            break;
        }
    }
}